package com.urbansquall.ginger.tools
{
	
	import com.urbansquall.ginger.Animation;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class AnimationBuilder
	{
		public static function importStrip(
			a_fps : int, a_bitmapData : BitmapData,
			a_tileWidth : int, a_tileHeight : int, a_tileCount : int = -1,
			a_startingX : int = 0, a_startingY : int = 0, a_rotations : int = 1, a_offsetX : int = 0, a_offsetY : int = 0  ) : Animation
		{
			var animation: Animation = new Animation( a_fps, a_rotations );
			
			var rows : int = Math.ceil( a_bitmapData.height / a_tileHeight );
			var cols : int = Math.ceil( a_bitmapData.width / a_tileWidth );

			var frameLocation : Rectangle;
			
			if( a_tileCount == -1 )
			{
				a_tileCount = rows * cols;
			}
			
			for( var i: int = 0; i < a_tileCount; i++ )
			{
				var tileX : int = (i % cols);
				var tileY : int = Math.floor( i / cols );
				frameLocation = new Rectangle(
					a_startingX + tileX * a_tileWidth, a_startingY + tileY * a_tileHeight,
					a_tileWidth, a_tileHeight );
				animation.addFrame( 1, a_bitmapData, frameLocation, a_tileWidth/2 + a_offsetX, a_tileHeight/2 + a_offsetY );
			}
			
			return animation;
		}
		
		/**
		 * Imports a MovieClip, Sprite, or Bitmap object and converts to an Animation object. 
		 * @param a_displayObject The object to import. Must be a MovieClip, Sprite, or Bitmap.
		 * @param a_fps The desired frame rate of the Animation
		 * @param a_rotations The number of Precached rotations to create
		 * @param a_offsetX X pixels to offset by
		 * @param a_offsetY Y pixels to offset by
		 * @param a_startFrame If a MovieClip is being imported, this is the frame to start importing from
		 * @param a_endFrame If a MovieClip is being imported, this is the last frame to import
		 * @return The newly generated Animation object
		 * 
		 */		
		public static function importDisplayObject( a_displayObject:DisplayObject, a_fps:int, a_rotations:int=1, a_offsetX:Number=0, a_offsetY:Number=0, a_startFrame:int=1, a_endFrame:int=-1 ) : Animation
		{
			var animation:Animation = new Animation( a_fps, a_rotations );
			if( a_displayObject is MovieClip )
			{
				return importMovieClip( a_displayObject as MovieClip, animation, a_offsetX, a_offsetY, a_startFrame, a_endFrame );
			}
			else if( a_displayObject is Sprite )
			{
				return importSprite( a_displayObject as Sprite, animation, a_offsetX, a_offsetY );
			}
			else if( a_displayObject is Bitmap )
			{
				return importBitmap( a_displayObject as Bitmap, animation, a_offsetX, a_offsetY );
			}
			
			throw new Error( "<AnimationBuilder> " + a_displayObject + " is an unsupported type!" );
		}
		
		private static function importMovieClip( a_movieClip:MovieClip, a_animation:Animation, a_offsetX:Number=0, a_offsetY:Number=0, a_startFrame:int=1, a_endFrame:int=-1 ) : Animation
		{
			var bd:BitmapData;
			var bounds:Rectangle;
			a_movieClip.gotoAndStop( a_startFrame );
			
			var ef:int = a_endFrame;
			if( ef == -1 || ef > a_movieClip.totalFrames )
			{
				ef = a_movieClip.totalFrames;
			}
			
			var i:int = a_startFrame;
			while( i <= ef )
			{
				bounds = a_movieClip.getBounds( a_movieClip );
				bd = new BitmapData(
                	Math.max(1, Math.min(2880, bounds.width)),
                	Math.max(1, Math.min(2880, bounds.height)),
                	true,
                	0x00000000);
                bd.draw(a_movieClip, new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y), null, null, null, true);
				a_animation.addFrame( 1, bd, bd.rect, bounds.x + a_offsetX, bounds.y + a_offsetY, a_movieClip.currentLabel );
				a_movieClip.nextFrame();
				i++
			}
			
			return a_animation;
		}	
		
		private static function importSprite( a_sprite:Sprite, a_animation:Animation, a_offsetX:Number=0, a_offsetY:Number=0 ) : Animation
		{
			
			var bounds:Rectangle = a_sprite.getBounds( a_sprite );
			var bd:BitmapData = new BitmapData(
            	Math.max(1, Math.min(2880, bounds.width)),
            	Math.max(1, Math.min(2880, bounds.height)),
            	true,
            	0x00000000);
            bd.draw(a_sprite, new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y), null, null, null, true);
			a_animation.addFrame( 1, bd, bd.rect, bounds.x + a_offsetX, bounds.y + a_offsetY );
			
			return a_animation;
		}	
		
		private static function importBitmap( a_bitmap:Bitmap, a_animation:Animation, a_offsetX:Number=0, a_offsetY:Number=0 ) : Animation
		{
			var bd:BitmapData;
			
			bd = new BitmapData( a_bitmap.width, a_bitmap.height, true, 0x00000000 );
			bd.copyPixels( a_bitmap.bitmapData, a_bitmap.bitmapData.rect, new Point() );
			a_animation.addFrame( 1, bd, bd.rect, a_offsetX, a_offsetY );
			
			return a_animation;
		}	
	}
}